package com.credithc.customers.api.service.impl;

import com.credithc.baseserv.core.convert.BaseConverter;
import com.credithc.baseserv.core.utils.UUIDUtils;
import com.credithc.customers.api.service.ICustomerInfoService;
import com.credithc.customers.base.codes.CustomerCodes;
import com.credithc.customers.base.constants.CustomerConstants;
import com.credithc.customers.base.constants.TableEnum;
import com.credithc.customers.base.exception.CustomerException;
import com.credithc.customers.base.factory.DictionaryFactory;
import com.credithc.customers.base.mapper.*;
import com.credithc.customers.base.po.*;
import com.credithc.customers.base.ro.*;
import com.credithc.customers.base.service.ICommonService;
import com.credithc.customers.base.utils.ClassUtils;
import com.credithc.customers.base.utils.CustomerUtils;
import com.credithc.customers.base.vo.CustomerQuerySubVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.sql.Date;
import java.sql.Timestamp;
import java.util.*;

/**
 * @Title: 客户信息维护实现类
 * @Author: Denghx
 * @Date: 2018/12/3 0:40
 * @Description: com.credithc.customers.api.service.impl
 * @Version: V1.0.0
 */
@Service
@Slf4j
public class CustomerInfoServiceImpl implements ICustomerInfoService {
    @Autowired
    private BizModifyMapper bizModifyMapper;
    @Autowired
    private CustomerRelationFlowMapper customerRelationFlowMapper;
    @Autowired
    private CustomerIdInfoMapper customerIdInfoMapper;
    @Autowired
    private CompanyIdInfoMapper companyIdInfoMapper;
    @Autowired
    BaseConverter<CustomerIdInfoRo, BizModifyPo> converterBizModifyRoToPo;
    @Autowired
    private CustomerAddFlowMapper customerAddFlowMapper;
    @Autowired
    private CustomerContactInfoMapper contactInfoMapper;
    @Autowired
    private CustomerRelationInfoMapper relationMapper;
    @Autowired
    private CustomerAccountMapper accountMapper;
    @Autowired
    private CustomerExtendMapper extendMapper;
    @Autowired
    private CustomerRoleMapper customerRoleMapper;
    @Autowired
    private ICommonService commonService;

    @Override
    public Map<String, Object> bizModify(BaseRequest<BizModifyRo> request) {
        log.info("接受业务方证件信息变更接口开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>入参:{}", request);
        try {
            checkBizParams(request);
            Map<String, Object> map = new HashMap<>(2);
            CustomerIdInfoRo idInfoRo = request.getBody().getIdInfo();
            BizModifyPo po = converterBizModifyRoToPo.convert(idInfoRo, BizModifyPo.class);
            po.setId(UUIDUtils.getUUID());
            if (StringUtils.isNotBlank(idInfoRo.getElementsTime())) {
                po.setElementsTime(CustomerUtils.stirng2Timestamp(idInfoRo.getElementsTime()));
            }
            po.setElementsVerified((idInfoRo.getElementsVerified() ? CustomerConstants.STATUS_ELEMENTS_VERIFIED : CustomerConstants.STATUS_ELEMENTS_UNVERIFIED));
            po.setSubSystemSign(request.getSubSystemSign());
            po.setSystemSign(request.getSystemSign());
            po.setCustomerNo(request.getBody().getCustomerNo());
            po.setRequestNo(request.getBody().getRequestNo());
            //待处理状态
            po.setStatus(CustomerConstants.CUSTOMER_RELATION_TODO);
            //通知状态-未通知
            po.setNoticeStatus(CustomerConstants.NOTICE_STATUS_TODO);
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            bizModifyMapper.insert(po);
            map.put("status", CustomerConstants.RECEIVE_STATUS_SUCCESS);
            return map;
        } catch (DataAccessException e) {
            log.info("业务证件信息变更异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

    public void checkBizParams(BaseRequest<BizModifyRo> request) {
        BizModifyRo.checkBaseParam(request.getBody());
        commonService.checkRepeatRequestNo(request.getBody().getRequestNo(), TableEnum.BIZ_MODIFY_FLOW);
        String customerNo = request.getBody().getCustomerNo();
        String prefix = customerNo.substring(0, 1);
        if (!CustomerConstants.IS_CUSTOMER_PREFIX.contains(prefix)) {
            throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "客户号" + customerNo + "不符合规则");
        }
        CustomerIdInfoPo po = commonService.getExistCustomer(customerNo, request.getSystemSign(), request.getSubSystemSign());
        if (po == null) {
            throw new CustomerException(CustomerCodes.CUSTOMERNO_NOT_EXIST, "客户号" + customerNo + "不存在");
        }
        //校验证件信息是否规范
        CustomerUtils.checkIdCardTypeAndNo(request.getBody().getIdInfo().getIdCardType(), request.getBody().getIdInfo().getIdCardNo());
    }

    @Override
    public void customerRelation(BaseRequest<CustomerRelationRo> request) {
        log.info("客户关联关系创建接口开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>入参:{}", request);
        try {
            CustomerRelationRo.checkBaseParam(request.getBody());
            List<CustomerRelationDetailRo> details = request.getBody().getRoles();
            CustomerRelationInfoPo infoPo = new CustomerRelationInfoPo();
            String requestNo = request.getBody().getRequestNo();
            checkRelation(request, details);
            for (CustomerRelationDetailRo detail : details) {
                infoPo.setId(UUIDUtils.getUUID());
                infoPo.setCustomerNo(detail.getCustomerNo());
                infoPo.setRelationId(requestNo);
                infoPo.setRoleInRelation(detail.getRole());
                infoPo.setRelationSource(CustomerConstants.CUSTOMER_RELATION_INTERFACE);//接口上送
                infoPo.setStatus(CustomerConstants.CUSTOMER_ROLE_EFFECTIVE);//角色有效
                infoPo.setSystemSign(request.getSystemSign());
                infoPo.setSubSystemSign(request.getSubSystemSign());
                infoPo.setCreateTime(new Timestamp(System.currentTimeMillis()));
                relationMapper.insert(infoPo);
            }
            insertCustomerRelationFlow(request, CustomerConstants.STATUS_SUCCESS);
        } catch (DataAccessException e) {
            log.info("插入客户关联关系表异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            insertCustomerRelationFlow(request, CustomerConstants.STATUS_FAIL);
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

    private void checkRelation(BaseRequest<CustomerRelationRo> request, List<CustomerRelationDetailRo> details) {
        commonService.checkRepeatRequestNo(request.getBody().getRequestNo(), TableEnum.RELATION_FLOW);
        // todo 客户关系去重校验
        HashSet<CustomerRelationDetailRo> hs = new HashSet<>(details);
        details.clear();
        details.addAll(hs);
        if (details.size() < 2) {
            throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "客户关系至少应两者或两者以上且不能重复");
        }
        for (CustomerRelationDetailRo detail : details) {
            if (detail.getCustomerProperty().equals(CustomerConstants.CUSTOMER_PROPERTY_OFFICIAL)) {
                CustomerIdInfoPo idInfoPo = commonService.getExistCustomer(detail.getCustomerNo(), request.getSystemSign(), request.getSubSystemSign());
                if (idInfoPo == null) {
                    throw new CustomerException(CustomerCodes.CUSTOMERNO_NOT_EXIST, "客户号" + detail.getCustomerNo() + "不存在");
                }
            } else {
                CustomerExtendPo extendPo = commonService.getExistPreCustomerExtend(detail.getCustomerNo(), request.getSystemSign(), request.getSubSystemSign());
                if (extendPo == null) {
                    throw new CustomerException(CustomerCodes.PRE_CUSTOMERNO_NOT_EXIST, "用户号" + detail.getCustomerNo() + "不存在");
                }
                if (StringUtils.isNotBlank(extendPo.getCustomerNo())) {
                    throw new CustomerException(CustomerCodes.PRE_CUSTOMERNO_CONVERTED, "该客户已转化客户号，客户号为" + extendPo.getCustomerNo() + "，请用对应客户号创建关系");
                }
                //若用户号已被关联其它用户号，失败，返回其关联用户号
                List<CustomerExtendPo> associatedList = commonService.getExistAssociatedPreCustomerExtendList(detail.getCustomerNo(), request.getSystemSign(), request.getSubSystemSign());
                if (associatedList.size() > 0) {
                    String message = "该客户号已被其他用户号关联,客户号为'" + associatedList.get(0).getPreCustomerNo() + "，请用对应客户号创建关系";
                    throw new CustomerException(CustomerCodes.PRE_CUSTOMERNO_CONVERTED, message);
                }
            }
        }
    }

    private void insertCustomerRelationFlow(BaseRequest<CustomerRelationRo> request, int status) {
        try {
            List<CustomerRelationDetailRo> details = request.getBody().getRoles();
            CustomerRelationFlowPo flowPo = new CustomerRelationFlowPo();
            String systemSign = request.getSystemSign();
            String subSystemSign = request.getSubSystemSign();
            String requestNo = request.getBody().getRequestNo();
            for (CustomerRelationDetailRo detail : details) {
                flowPo.setCustomerNo(detail.getCustomerNo());
                flowPo.setCustomerProperty(detail.getCustomerProperty());
                flowPo.setRequestNo(requestNo);
                flowPo.setId(UUIDUtils.getUUID());
                flowPo.setRole(detail.getRole());
                flowPo.setStatus(status);
                flowPo.setSubSystemSign(subSystemSign);
                flowPo.setSystemSign(systemSign);
                flowPo.setCreateTime(new Timestamp(System.currentTimeMillis()));
                customerRelationFlowMapper.insert(flowPo);
            }
        } catch (DataAccessException e) {
            log.info("插入客户关联关系流水异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

    @Override
    public Map<String, Object> queryThreeElements(BaseRequest<ThreeElementsRo> request) {
        log.info("三要素查询入参接口开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>入参:{}", request);
        try {
            ThreeElementsRo.checkBaseParam(request.getBody());
            Map<String, Object> map = new HashMap<>(2);
            CustomerIdInfoPo po = new CustomerIdInfoPo();
            po.setIdCardType(request.getBody().getIdCardType());
            po.setCustomerName(request.getBody().getCustomerName());
            po.setIdCardNo(request.getBody().getIdCardNo());
            List<CustomerIdInfoPo> list = customerIdInfoMapper.select(po);
            if (list.size() == 0) {
                throw new CustomerException(CustomerCodes.BIZ_VALIDATE_ERROR, "证件信息不存在");
            }
            Boolean elementsVerified = list.get(0).getElementsVerified().equals(CustomerConstants.STATUS_ELEMENTS_VERIFIED) ? true : false;
            map.put("elementsVerified", elementsVerified);
            return map;
        } catch (DataAccessException e) {
            log.info("三要素核验状态查询异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }
    }

    @Override
    public Map<String, Object> getCustomerInfo(BaseRequest<CustomerQueryRo> request) {
        log.info("客户基本信息查询接口开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>入参:{}", request);
        try {
            CustomerQueryRo.checkBaseParam(request.getBody());
            Map<String, Object> map = new HashMap<>(2);
            String customerNo = request.getBody().getCustomerNo();
            String prefix = customerNo.substring(0, 1);
            if (!(CustomerConstants.PRE_CUSTOMER_PREFIX.equals(prefix)
                    || CustomerConstants.IS_CUSTOMER_PREFIX.contains(prefix))) {
                throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "客户号" + customerNo + "不符合定义规则");
            }
            //判断客户号/用户号是否存在 ，分别封装用户信息与客户信息,用户号需查询出扩展证件信息
            if (CustomerConstants.PRE_CUSTOMER_PREFIX.equals(prefix)) {
                PreCustomerInfoPo preCustomerInfoPo = commonService.getExistPreCustomer(customerNo);
                if (preCustomerInfoPo == null) {
                    throw new CustomerException(CustomerCodes.PRE_CUSTOMERNO_NOT_EXIST);
                }
                map = queryPreCustomerInfo(request, customerNo, preCustomerInfoPo);
            } else {
                CustomerInfoPo customerInfoPo = commonService.getExistCustomer(customerNo);
                if (customerInfoPo == null) {
                    throw new CustomerException(CustomerCodes.CUSTOMERNO_NOT_EXIST);
                }
                map = queryCustomerInfo(request, customerNo, customerInfoPo);
            }
            return map;
        } catch (DataAccessException e) {
            log.info("客户基本信息查询异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }
    }

    public Map<String, Object> queryCustomerInfo(BaseRequest request, String customerNo, CustomerInfoPo customerInfoPo) {
        try {
            Map<String, Object> map = new HashMap();
            List<Map<String, Object>> companyIdInfos = new ArrayList<>();
            List<Map<String, Object>> contacts = new ArrayList<>();
            String customerType = customerInfoPo.getCustomerType();
            String createTime = CustomerUtils.timestamp2Stirng(customerInfoPo.getCreateTime());
            String systemSign = request.getSystemSign();
            String subSystemSign = request.getSubSystemSign();
            map.put("customerNo", customerNo);
            map.put("customerProperty", "客户");
            map.put("customerType", DictionaryFactory.Dict.CUSTOMER_TYPE.getDictMap().get(customerType));
            map.put("createTime", createTime);
            if (CustomerConstants.CUSTOMER_TYPE_PERSON.equals(customerType)) {
                List<Map<String, Object>> idInfos = getCustomerIdInfo(request, customerNo);
                map.put("idInfos", idInfos);
            } else {
                //企业证件信息
                Example example = new Example(CompanyIdInfoPo.class);
                example.setDistinct(false);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("customerNo", customerNo);
                List<CompanyIdInfoPo> companyInfoList = companyIdInfoMapper.selectByExample(example);
                if (companyInfoList.size() > 0) {
                    for (CompanyIdInfoPo companyIdInfoPo : companyInfoList) {
                        Map<String, Object> companyIdInfo = new HashMap<>();
                        companyIdInfo.put("customerName", companyIdInfoPo.getCustomerName());
                        companyIdInfo.put("idCardType", DictionaryFactory.Dict.ID_TYPE.getDictMap().get(companyIdInfoPo.getIdCardType()));
                        companyIdInfo.put("idCardNo", companyIdInfoPo.getIdCardNo());
                        companyIdInfo.put("orgNo", companyIdInfoPo.getOrgNo());
                        companyIdInfo.put("licenseNo", companyIdInfoPo.getLicenseNo());
                        companyIdInfo.put("taxNo", companyIdInfoPo.getTaxNo());
                        companyIdInfo.put("unifiedCode", companyIdInfoPo.getUnifiedCode());
                        companyIdInfo.put("elementsVerified", companyIdInfoPo.getElementsVerified().equals(CustomerConstants.STATUS_ELEMENTS_VERIFIED) ? true : false);
                        companyIdInfos.add(companyIdInfo);
                    }
                    map.put("companyIdInfos", companyIdInfos);
                }
            }
            //客户联系信息
            Example example1 = new Example(CustomerContactInfoPo.class);
            example1.setDistinct(false);
            Example.Criteria criteria1 = example1.createCriteria();
            criteria1.andEqualTo("customerNo", customerNo);
            criteria1.andEqualTo("systemSign", systemSign);
            criteria1.andEqualTo("subSystemSign", subSystemSign);
            List<CustomerContactInfoPo> customerContactInfoList = contactInfoMapper.selectByExample(example1);
            if (customerContactInfoList.size() > 0) {
                for (CustomerContactInfoPo contactPo : customerContactInfoList) {
                    Map<String, Object> contact = new HashMap<>();
                    contact.put("contactType", DictionaryFactory.Dict.CONTACT_TYPE.getDictMap().get(contactPo.getContactType()));
                    contact.put("contactInfo", contactPo.getContactInfo());
                    contacts.add(contact);
                }
                map.put("contacts", contacts);
            }
            //TODO 客户角色信息  后续接入产品与账户才有角色信息维护
            List<Map<String, Object>> customerRoles = getCustomerRoles(request, customerNo);
            map.put("customerRoles", customerRoles);
            return map;
        } catch (DataAccessException e) {
            log.info("客户查询报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }
    }

    private List<Map<String, Object>> getCustomerIdInfo(BaseRequest request, String customerNo) {
        try {
            List<Map<String, Object>> idInfos = new ArrayList<>();
            List<CustomerIdInfoPo> pos = commonService.getAllCustomer(customerNo, request.getSystemSign(), request.getSubSystemSign());
            //个人证件信息
            if (pos.size() > 0) {
                for (CustomerIdInfoPo idInfoPo : pos) {
                    Map<String, Object> idInfo = new HashMap<>();
                    idInfo.put("customerName", idInfoPo.getCustomerName());
                    idInfo.put("idCardType", DictionaryFactory.Dict.ID_TYPE.getDictMap().get(idInfoPo.getIdCardType()));
                    idInfo.put("idCardNo", idInfoPo.getIdCardNo());
                    idInfo.put("elementsVerified", idInfoPo.getElementsVerified().equals(CustomerConstants.STATUS_ELEMENTS_VERIFIED) ? true : false);
                    idInfos.add(idInfo);
                }
            }
            return idInfos;
        } catch (DataAccessException e) {
            log.info("查询个人客户证件信息异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }
    }

    private List<Map<String, Object>> getCustomerRoles(BaseRequest request, String customerNo) {
        try {
            List<Map<String, Object>> customerRoles = new ArrayList<>();
            Example example = new Example(CustomerRolePo.class);
            example.setDistinct(false);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("customerNo", customerNo);
            criteria.andEqualTo("systemSign", request.getSystemSign());
            criteria.andEqualTo("subSystemSign", request.getSubSystemSign());
            List<CustomerRolePo> rolePoList = customerRoleMapper.selectByExample(example);
            if (rolePoList.size() > 0) {
                for (CustomerRolePo rolePo : rolePoList) {
                    Map<String, Object> customerRole = new HashMap<>();
                    customerRole.put("customerRole", DictionaryFactory.Dict.ROLE.getDictMap().get(rolePo.getCustomerRole()));
                    customerRoles.add(customerRole);
                }
            }
            return customerRoles;
        } catch (DataAccessException e) {
            log.info("查询客户角色报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }
    }

    private List<Map<String, Object>> getChangeInfo(BaseRequest request, String preCustomerNo) {
        try {
            List<Map<String, Object>> changeInfos = new ArrayList<>();
            Example example = new Example(CustomerExtendPo.class);
            example.setDistinct(false);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("preCustomerNo", preCustomerNo);
            criteria.andEqualTo("systemSign", request.getSystemSign());
            criteria.andEqualTo("subSystemSign", request.getSubSystemSign());
            criteria.andIsNotNull("customerNo");
            List<CustomerExtendPo> pos = extendMapper.selectByExample(example);
            if (pos.size() > 0) {
                for (CustomerExtendPo po : pos) {
                    Map<String, Object> changeInfo = new HashMap<>();
                    changeInfo.put("customerNo", po.getCustomerNo());
                    changeInfos.add(changeInfo);
                }
            }
            return changeInfos;
        } catch (DataAccessException e) {
            log.info("查询客户转化情况报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }
    }

    public Map<String, Object> queryPreCustomerInfo(BaseRequest request, String preCustomerNo, PreCustomerInfoPo preCustomerInfoPo) {
        Map<String, Object> map = new HashMap();
        List<Map<String, Object>> contacts = new ArrayList<>();
        Map<String, Object> contact = new HashMap<>();
        String createTime = CustomerUtils.timestamp2Stirng(preCustomerInfoPo.getCreateTime());
        map.put("customerNo", preCustomerNo);
        map.put("customerProperty", "用户");
        map.put("createTime", createTime);
        //客户联系信息
        contact.put("contactType", DictionaryFactory.Dict.CONTACT_TYPE.getDictMap().get(preCustomerInfoPo.getContactType()));
        contact.put("contactInfo", preCustomerInfoPo.getContactInfo());
        contacts.add(contact);
        map.put("contacts", contacts);
        //TODO 客户角色信息  后续接入产品与账户才有角色信息维护
//        List<Map<String, Object>> customerRoles = getCustomerRoles(request, preCustomerNo);
//        map.put("customerRoles", customerRoles);
        //用户扩展信息
        List<Map<String, Object>> idInfos = getCustomerIdInfo(request, preCustomerNo);
        map.put("idInfos", idInfos);
        //用户转化信息
        List<Map<String, Object>> changeInfos = getChangeInfo(request, preCustomerNo);
        map.put("changes", changeInfos);
        return map;
    }

    @Override
    public Map<String, String> addCustomerInfo(BaseRequest<CustomerInfoAddRo> request) {
        try {
            CustomerInfoAddRo.checkBaseParam(request.getBody());
            commonService.checkRepeatRequestNo(request.getBody().getRequestNo(), TableEnum.ADD_FLOW);
            Map<String, String> map = new HashMap<>(1);
            if (!request.getBody().getCustomerNo().startsWith(CustomerConstants.PERSONAL_CUSTOMER_PREFIX)) {
                throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "只支持个人客户新增");
            }
            CustomerInfoPo customerInfoPo = commonService.getExistCustomer(request.getBody().getCustomerNo());
            if (customerInfoPo == null) {
                throw new CustomerException(CustomerCodes.CUSTOMERNO_NOT_EXIST);
            }
            Integer type = request.getBody().getType();
            if (type.equals(CustomerConstants.ADD_CONTACT_INFO)) {
                addContactInfo(request);
            } else if (type.equals(CustomerConstants.ADD_ID_INFO)) {
                addIdInfo(request);
            } else if (type.equals(CustomerConstants.ADD_ID_CONTACT_INFO)) {
                ((CustomerInfoServiceImpl) AopContext.currentProxy()).addContactAndIdInfo(request);
            }
            map.put("customerNo", request.getBody().getCustomerNo());
            insertAddFlow(request, CustomerConstants.STATUS_SUCCESS, null);
            return map;
        } catch (CustomerException e) {
            log.info("新增客户信息失败" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName());
            insertAddFlow(request, CustomerConstants.STATUS_FAIL, e.getMsg());
            throw new CustomerException(e.getCode(), e.getMsg());
        }

    }

    private void addContactInfo(BaseRequest<CustomerInfoAddRo> request) {
        try {
            String systemSign = request.getSystemSign();
            String subSystemSign = request.getSubSystemSign();
            String customerNo = request.getBody().getCustomerNo();
            ContactRo contact = request.getBody().getContact();
            if (contact == null) {
                throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "type是" + request.getBody().getType() + "时,contact必填");
            } else {
                ContactRo.checkBaseParam(contact);
                CustomerContactInfoPo contactPo = new CustomerContactInfoPo();
                contactPo.setCustomerNo(customerNo);
                contactPo.setSystemSign(systemSign);
                contactPo.setSubSystemSign(subSystemSign);
                contactPo.setContactType(contact.getContactType());
                contactPo.setContactInfo(contact.getContactInfo());
                int res = contactInfoMapper.selectCount(contactPo);
                if (res > 0) {
                    log.info("联系信息已经存在" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName());
                    throw new CustomerException(CustomerCodes.BIZ_VALIDATE_ERROR, "联系信息已存在");
                }
                commonService.insertCustomerContactInfo(contact, customerNo, request, null);
            }
        } catch (DataAccessException e) {
            log.info("查询存在的联系信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }

    }

    private void addIdInfo(BaseRequest<CustomerInfoAddRo> request) {
        try {
            String customerNo = request.getBody().getCustomerNo();
            CustomerIdInfoRo idInfo = request.getBody().getIdInfo();
            if (idInfo == null) {
                throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "type是" + request.getBody().getType() + "时,idInfo必填");
            } else {
                CustomerIdInfoRo.checkBaseParam(idInfo);

                CustomerIdInfoPo existCustomer = commonService.getExistCustomer(customerNo, request.getSystemSign(), request.getSubSystemSign());
                if (existCustomer == null) {
                    throw new CustomerException(CustomerCodes.CUSTOMERNO_NOT_EXIST);
                }
                CustomerIdInfoPo idInfoPo = new CustomerIdInfoPo();
                idInfoPo.setCustomerNo(customerNo);
                idInfoPo.setCustomerName(idInfo.getCustomerName());
                idInfoPo.setIdCardType(idInfo.getIdCardType());
                idInfoPo.setIdCardNo(idInfo.getIdCardNo());
                int res = customerIdInfoMapper.selectCount(idInfoPo);
                if (res > 0) {
                    log.info("三要素信息已经存在" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName());
                    throw new CustomerException(CustomerCodes.BIZ_VALIDATE_ERROR, "证件信息已存在");
                }
                commonService.insertCustomerIdInfo(idInfo, customerNo, request.getSubSystemSign(), null, false);
            }
        } catch (DataAccessException e) {
            log.info("查询存在的id信息报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void addContactAndIdInfo(BaseRequest<CustomerInfoAddRo> request) {
        addContactInfo(request);
        addIdInfo(request);
    }

    private void insertAddFlow(BaseRequest<CustomerInfoAddRo> request, Integer status, String remark) {
        CustomerAddFlowPo po = new CustomerAddFlowPo();
        po.setId(UUIDUtils.getUUID());
        po.setRequestNo(request.getBody().getRequestNo());
        po.setCustomerNo(request.getBody().getCustomerNo());
        po.setSystemSign(request.getSystemSign());
        po.setSubSystemSign(request.getSubSystemSign());
        po.setStatus(status);
        po.setType(request.getBody().getType());
        if (StringUtils.isNotBlank(remark)) {
            po.setRemark(remark);
        }
        Integer type = request.getBody().getType();
        ContactRo contact = request.getBody().getContact();
        CustomerIdInfoRo idInfo = request.getBody().getIdInfo();
        if (type != null) {
            if (type.equals(CustomerConstants.ADD_CONTACT_INFO)) {
                generateContactFlowPo(po, contact);
            } else if (type.equals(CustomerConstants.ADD_ID_INFO)) {
                generateIdFlowPo(po, idInfo);
            } else if (type.equals(CustomerConstants.ADD_ID_CONTACT_INFO)) {
                generateContactFlowPo(po, contact);
                generateIdFlowPo(po, idInfo);
            }
        }
        try {
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            po.setCreateDate(new Date(System.currentTimeMillis()));
            customerAddFlowMapper.insert(po);
        } catch (DataAccessException e) {
            log.info("插入客户新增流水报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

    private void generateIdFlowPo(CustomerAddFlowPo po, CustomerIdInfoRo idInfo) {
        if (idInfo != null) {
            po.setCustomerName(idInfo.getCustomerName());
            po.setIdCardType(idInfo.getIdCardType());
            po.setIdCardNo(idInfo.getIdCardNo());
            po.setElementsVerified((idInfo.getElementsVerified() != null && idInfo.getElementsVerified()) ? CustomerConstants.STATUS_ELEMENTS_VERIFIED : CustomerConstants.STATUS_ELEMENTS_UNVERIFIED);
            if (StringUtils.isNotBlank(idInfo.getElementsTime())) {
                po.setElementsTime(CustomerUtils.stirng2Timestamp(idInfo.getElementsTime()));
            }
        }
    }

    private void generateContactFlowPo(CustomerAddFlowPo po, ContactRo contact) {
        if (contact != null) {
            po.setContactType(contact.getContactType());
            po.setContactInfo(contact.getContactInfo());
            po.setContactVerified((contact.getContactVerified() != null && contact.getContactVerified()) ? CustomerConstants.STATUS_CONTACT_VERIFIED : CustomerConstants.STATUS_CONTACT_UNVERIFIED);
        }
    }


    @Override
    public Map<String, Object> queryAccount(BaseRequest<CustomerAccountRo> request) {
        log.info("客户账户信息查询接口开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>入参:{}", request);
        try {
            CustomerAccountRo.checkBaseParam(request.getBody());
            //校验客户号是否存在
            String customerNo = request.getBody().getCustomerNo();
            String prefix = customerNo.substring(0, 1);
            if (!(CustomerConstants.PRE_CUSTOMER_PREFIX.equals(prefix)
                    || CustomerConstants.IS_CUSTOMER_PREFIX.contains(prefix))) {
                throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "客户号" + customerNo + "不符合定义规则");
            }
            if (CustomerConstants.PRE_CUSTOMER_PREFIX.equals(prefix)) {
                commonService.getExistCustomer(customerNo);
            } else {
                commonService.getExistPreCustomer(customerNo);
            }
            Map<String, Object> map = new HashMap<>(2);
            List<Map<String, Object>> accountInfos = new ArrayList<>();
            CustomerAccountPo accountPo = new CustomerAccountPo();
            accountPo.setCustomerNo(customerNo);
            List<CustomerAccountPo> list = accountMapper.select(accountPo);
            if (list.size() > 0) {
                for (CustomerAccountPo po : list) {
                    Map<String, Object> accountInfo = new HashMap<>();
                    accountInfo.put("accounNo", po.getAccountNo());
                    accountInfo.put("accounType", po.getAccountType());
                    accountInfo.put("accountStatus", po.getAccountStatus().equals(CustomerConstants.STATUS_ACCOUNT_AVAILABLE) ? "可用" : "不可用");
                    accountInfo.put("systemSign", po.getSystemSign());
                    accountInfo.put("subSystemSign", po.getSubSystemSign());
                    accountInfos.add(accountInfo);
                }
            }
            map.put("accountInfos", accountInfos);
            return map;
        } catch (DataAccessException e) {
            log.info("客户账户信息查询异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }
    }

    @Override
    public Map<String, Object> byMobileAndId(BaseRequest<CustomerQuerySubRo> request) {
        log.info("智能客服查询接口开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>入参:{}", request);
        Map<String, Object> map = new HashMap<>(2);
        Map<String, Object> resMap = new HashMap<>(2);
        try {
            CustomerQuerySubRo ro = request.getBody();
            CustomerQuerySubRo.checkBaseParam(ro);
//            Map<String, Object> map = new HashMap<>();
            String systemSign = request.getSystemSign();
            String subSystemSign = request.getSubSystemSign();
            if (!(CustomerConstants.ZNKF.equals(systemSign) && CustomerConstants.ZNKF.equals(subSystemSign))) {
                throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "本接口不支持当前系统");
            }
            resMap.put("requestNo", ro.getRequestNo());
            resMap.put("systemSign", systemSign);
            //智能客服接口身份证信息X用*代替，此处需要改回X
            String idcard = ro.getIdcard().replace('*', 'X');
            CustomerUtils.checkIdCard(idcard);
            ro.setIdcard(idcard);
            List<Map<String, Object>> platforms = new ArrayList<>();
            List<CustomerQuerySubVo> dataList = customerIdInfoMapper.querySubSystemSigns(ro);
            log.info("智能客服查询>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>结果:{}", dataList);
            if (dataList != null && dataList.size() > 0) {
                resMap.put("customerNo", dataList.get(0).getCustomerNo());
                resMap.put("idcard", idcard);
                for (CustomerQuerySubVo vo : dataList) {
                    Map<String, Object> platformInfo = new HashMap<>();
                    platformInfo.put("registerTime", vo.getCreateTime());
                    //平台类型
                    Map<String, String> platformMap = DictionaryFactory.Dict.PLATFORM_TYPE.getDictMap();
                    if (StringUtils.isNotEmpty(vo.getSystemSign())) {
                        platformInfo.put("platform", platformMap.get(vo.getSystemSign()));
                    }
                    if (vo.getSubSystemSign().contains("JK")) {
                        platformInfo.put("type", CustomerConstants.USER_JK);
                    }
                    if (vo.getSubSystemSign().contains("CF")) {
                        platformInfo.put("type", CustomerConstants.USER_CF);
                    }
                    if ("HYD".equals(vo.getSubSystemSign())) {
                        platformInfo.put("type", CustomerConstants.USER_JK);
                    }
                    platforms.add(platformInfo);
                }
                resMap.put("platforms", platforms);
            } else {
                throw new CustomerException(CustomerCodes.ZNKF_ERROR_QUERY, "用户不是恒昌客户");
            }
            map.put("resMap", resMap);
            return map;
        } catch (CustomerException e) {
            log.error("智能客服查询异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            Integer code = e.getCode();
            String msg = e.getMsg();
            if (code.equals(CustomerCodes.PARAM_VALIDATE_ERROR)) {
                map.put("msg", msg);
                map.put("code", code);
                return map;
            } else {
                throw new CustomerException(e.getCode(), e.getMsg());
            }
        }
    }

}
